<?php
class MessageParser {
	const ABOVELINESTR = '--- Reply ABOVE THIS LINE to post a reply to the message ---';

	public static function parse($file) {
		if(file_exists($file)) {
			echo "Parsing Mail File: $file \n";
			$set = new ezcMailFileSet(array($file));
			$parser = new ezcMailParser();
			$mail = $parser->parseMail($set);
			// self::formatMail($mail[0]);
			$mail_item = $mail[0];
			
			// begin parsing the recipient destination to find the recipient, group, and origin id
			$destination_email = $mail_item->to[0]->email;
			$position = strrpos($destination_email, '@');
			if($position !== false) {
				$encoded_destination = substr($destination_email, 0, $position);		
				echo "encoded destination: $encoded_destination \n";
				$elements = explode('-', $encoded_destination);
				print_r($elements);
				foreach($elements as $element) {
					switch($element[0]) {
						// retrieve the user id of the original recipient who is now the sender				
						case 'U':
							$sender_id = ltrim($element, 'U');
							echo "sender_id: $sender_id \n";					
						break;
						
						// retrieve the sender id of the original sender who will now be the recipient
						case 'S':
							$recipient_id = ltrim($element, 'S');
							echo "recipient_id: $recipient_id \n";
						break;
						
						// retrieve the original id of the orign message
						case 'I':
							$message_id = ltrim($element, 'I');
							echo "message_id: $message_id \n";
						break;
						
						// retrieve the history id of the conversation
						case 'H':
							$history_id = ltrim($element, 'H');
							echo "history_id: $history_id \n";
						break;
						
						// retrieve the group id if the message is intended for a group
						case 'G':
							$group_id = ltrim($element, 'G');
							echo "group_id: $group_id \n";
						break;
					}
				}
				
				// retrieve the subject
				$subject = $mail_item->subject;
				echo "subject: $subject \n";
				
				$body = self::formatMailPart($mail_item->body);
				// format the body and find the response message
				$ratl_pos = strrpos($body, MessageParser::ABOVELINESTR);
				if($ratl_pos !== false) {
					$body = substr($body, 0, $ratl_pos);
					preg_match('/\n.*wrote:(.*?)/i', $body, $matches);
					if(isset($matches[0])) {
						$extra_info = strrpos($body, $matches[0]);
						if($extra_info !== false) {
							$body = substr($body, 0, $extra_info);
						}						
					}
					$body = preg_replace('/\n.*wrote:(.*?)/', '', $body);					
					$body = trim($body);
				} else {
					echo "error: Reply Above THIS LINE indicator was not found within the message.";
					return false;
				}
				
				echo "body: $body \n\n";
								
				if(isset($group_id) && $group_id) {
					// retrieve all members of the group
					$group_members = GroupMemberPeer::retrieveByGroupId($group_id, GroupMemberPeer::APPROVED_STATUS);
					foreach($group_members as $group_member) {				
						$message = new Message();
						$message->setSenderId($sender_id);
						$message->setOriginId($message_id);
						$message->setMessageHistoryId($history_id);
						$message->setType(MessagePeer::GROUP_TYPE);
						$message->setTypeId($group_id);				
						$message->setUserId($group_member->getUserId());
						$message->setReplied(null);
						
						if($sender_id == $group_member->getUserId()) {
							$message->setFolder(MessagePeer::SENT_FOLDER);
						} else {
							$message->setFolder(MessagePeer::INBOX_FOLDER);
							$message->setRecipientId($group_member->getUserId());					
						}
						$message->setSubject($subject);
						$message->setBody($body);
						echo "saving group message for ".$group_member->getUser()->getFullName()."\n";
						$message->save();	
					}
				} else {
					// store the message in the sender's sent box
					$message = new Message();
					$message->setSenderId($sender_id);
					$message->setOriginId($message_id);
					$message->setMessageHistoryId($history_id);
					$message->setType(MessagePeer::GROUP_TYPE);
					$message->setTypeId($group_id);				
					$message->setFolder(MessagePeer::SENT_FOLDER);
					$message->setSubject($subject);
					$message->setBody($body);
					$message->setUserId($sender_id);
					$message->save();					
					
					// re-create message and store it in the recipients inbox
					$message->setNew(true);
					$message->setUserId($recipient_id);
					$message->setFolder(MessagePeer::INBOX_FOLDER);
					$message->setRecipientId($recipient_id);					
					$message->save();			
				}
				
			}
			
			echo "\n\n";
			return true;
		} else {
			echo "\n $file does not exist";
			return false;
		}
	
	}
	
	public static function formatMailPart( $part )
	{
	    if ( $part instanceof ezcMail )
	        return self::formatMail( $part );
	
	    if ( $part instanceof ezcMailText )
	        return self::formatMailText( $part );
	
	    if ( $part instanceof ezcMailFile )
	        return self::formatMailFile( $part );
	
	    if ( $part instanceof ezcMailRfc822Digest )
	        return self::formatMailRfc822Digest( $part );
	
	    if ( $part instanceof ezcMailMultiPart )
	        return self::formatMailMultipart( $part );
	
	    die( "No clue about the ". get_class( $part ) . "\n" );
	}
	
	public static function formatMailMultipart( $part )
	{
	    if ( $part instanceof ezcMailMultiPartAlternative )
	        return self::formatMailMultipartAlternative( $part );
	
	    if ( $part instanceof ezcMailMultiPartDigest )
	        return self::formatMailMultipartDigest( $part );
	
	    if ( $part instanceof ezcMailMultiPartRelated )
	        return self::formatMailMultipartRelated( $part );
	
	    if ( $part instanceof ezcMailMultiPartMixed )
	        return self::formatMailMultipartMixed( $part );
	
	    die( "No clue about the ". get_class( $part ) . "\n" );
	}
	
	public static function formatMailMultipartMixed( $part )
	{
	    $t = '';
	    foreach ( $part->getParts() as $key => $alternativePart )
	    {
	        $t .= self::formatMailPart( $alternativePart );
	    }
	    return $t;
	}
	
	public static function formatMailMultipartRelated( $part )
	{
	    $t = '';
	    $t .= self::formatMailPart( $part->getMainPart() );
	    foreach ( $part->getRelatedParts() as $key => $alternativePart) {
	        $t .= self::formatMailPart( $alternativePart );
	    }
	    return $t;
	}
	
	public static function formatMailMultipartDigest( $part )
	{
	    $t = '';
	    foreach ( $part->getParts() as $key => $alternativePart) {
	        $t .= self::formatMailPart( $alternativePart );
	    }
	    return $t;
	}
	
	public static function formatMailRfc822Digest( $part )
	{
	    $t = '';
	    $t .= self::formatMailpart( $part->mail );
	    return $t;
	}
	
	public static function formatMailMultipartAlternative( $part )
	{
	    $t = '';
	    foreach ( $part->getParts() as $key => $alternativePart ) {
	        $t .= self::formatMailPart( $alternativePart );
	    }
	    return $t;
	}
	
	public static function formatMailText( $part )
	{
	    $t = '';
		// retrieve only plain text emails
		if($part->subType == 'plain') {
	   		$t .= "{$part->text}";		
		}
	    return $t;
	}	
	
	public static function formatMailFile( $part ) {
	    $t = '';
	    $t .= "Disposition Type: {$part->dispositionType}\n";
	    $t .= "Content Type:     {$part->contentType}\n";
	    $t .= "Mime Type:        {$part->mimeType}\n";
	    $t .= "Content ID:       {$part->contentId}\n";
	    $t .= "Filename:         {$part->fileName}\n";
	    $t .= "\n";
	    return $t;
	}
	
	public static function formatAddresses( $addresses )
	{
	    $fa = array();
	    foreach ( $addresses as $address )
	    {
	        $fa[] = self::formatAddress( $address );
	    }
	    return implode( ', ', $fa );
	}
	
	public static function formatAddress( $address )
	{
	    $name = '';
	    if ( !empty( $address->name ) )
	    {
	        $name = "{$address->name}";
	    }
	    return $name . "<{$address->email}>";
	}

}
